package com.gd.iot.energy.service.datamanage.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.datamanage.EquipInstructionValuePOMapper;
import com.gd.iot.energy.dao.datamanage.EquipInstructiontreePOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.datamanage.EquipInstructionValuePO;
import com.gd.iot.energy.po.datamanage.EquipInstructionValuePOWithBLOBs;
import com.gd.iot.energy.po.datamanage.EquipInstructiontreePO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.datamanage.vo.InstructionPageVO;
import com.gd.iot.energy.pojo.statistics.vo.CalledDetailVO;
import com.gd.iot.energy.pojo.statistics.vo.ReceiveDetailVO;
import com.gd.iot.energy.service.datamanage.InstructionService;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomStrUtil;
import com.gd.iot.energy.util.EnergyTypeUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author kris
 * @date 2020/8/13 0013 15:50
 */
@Service
public class InstructionServiceImpl extends ServiceImpl<EquipInstructionValuePOMapper, EquipInstructionValuePOWithBLOBs> implements InstructionService {

    @Resource
    private EquipInstructionValuePOMapper equipInstructionValuePOMapper;

    @Resource
    private EquipInstructiontreePOMapper equipInstructiontreePOMapper;


    /**
     * 指令收发记录表头配置文件
     */
    private static final String INSTRUCTION_LIST_COLUMN_FILE_NAME = "datamanage/instruction_list.column";


    @Override
    public PageVO<InstructionPageVO> getInstructionPageVO(Integer equipmentType, String archivesNum,
                                                          String areaName,
                                                          String archivesAddress, String archivesName,
                                                          String beginDate, String endDate,
                                                          Integer pageSize, Integer pageNum,
                                                          String orderColumn, String orderType) {
        IPage<EquipInstructionValuePOWithBLOBs> page = new Page<>(pageNum, pageSize);
        QueryWrapper<EquipInstructionValuePOWithBLOBs> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        if (StrUtil.isNotBlank(areaName)) {
            queryWrapper.like("area_name", areaName);
        }
        if (StrUtil.isNotBlank(archivesNum)) {
            queryWrapper.like("archives_num", archivesNum);
        }
        if (equipmentType != null) {
            queryWrapper.like("equipment_type", equipmentType);
        }
        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("archives_address", archivesAddress);
        }
        if (StrUtil.isNotBlank(beginDate)) {
            queryWrapper.ge("create_date", DateUtil.beginOfDay(DateUtil.parseDate(beginDate)));
        }
        if (StrUtil.isNotBlank(endDate)) {
            queryWrapper.le("create_date", DateUtil.beginOfDay(DateUtil.parseDate(endDate)));
        }

        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }

        IPage<EquipInstructionValuePOWithBLOBs> equipInstructionValuePOPage = equipInstructionValuePOMapper.selectPage(page, queryWrapper);
        PageVO<InstructionPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<InstructionPageVO> meterStatusPageVOS = convertToInstructionPageVOList(equipInstructionValuePOPage.getRecords());
        pageVO.setData(meterStatusPageVOS);
        pageVO.setTotal(equipInstructionValuePOPage.getTotal());
        pageVO.setPages(equipInstructionValuePOPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(INSTRUCTION_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    @Override
    public CalledDetailVO calledDetail(Integer id) {
        EquipInstructionValuePOWithBLOBs equipInstructionValue = equipInstructionValuePOMapper.selectById(id);
        if (equipInstructionValue == null) {
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }
        EquipInstructiontreePO equipInstructTree = equipInstructiontreePOMapper.selectById(equipInstructionValue.getTreeId());
        CalledDetailVO calledDetailVO = new CalledDetailVO();
        calledDetailVO.setTitle(equipInstructTree==null?null:equipInstructTree.getTreeName());
        calledDetailVO.setTotalNumber(equipInstructionValue.getPn());

        calledDetailVO.setPackageVOS(equipInstructionValue.getCalledValue());
        return calledDetailVO;
    }

    @Override
    public ReceiveDetailVO receiveDetail(Integer id) {
        EquipInstructionValuePOWithBLOBs equipInstructionValue = equipInstructionValuePOMapper.selectById(id);
        if (equipInstructionValue == null) {
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }
        EquipInstructiontreePO equipInstructTree = equipInstructiontreePOMapper.selectById(equipInstructionValue.getTreeId());
        final JSONObject parseObj = JSONUtil.parseObj(equipInstructionValue.getParseJsonStr());
        ReceiveDetailVO receiveDetailVO = new ReceiveDetailVO();
        receiveDetailVO.setTitle(equipInstructTree==null?null:equipInstructTree.getTreeName());
        receiveDetailVO.setImei(equipInstructionValue.getNbAddress());
        receiveDetailVO.setValues(equipInstructionValue.getParseJsonStr());

        return receiveDetailVO;
    }


    /**
     * 指令po转vo
     *
     * @param records
     * @return
     */
    private List<InstructionPageVO> convertToInstructionPageVOList(List<EquipInstructionValuePOWithBLOBs> records) {
        List<Long> treeIds = records.stream().map(EquipInstructionValuePO::getTreeId).collect(Collectors.toList());
        Map<Long, String> treeIdNameMap = new HashMap<>();
        if (!treeIds.isEmpty()) {
            List<EquipInstructiontreePO> equipInstructiontreePOS = equipInstructiontreePOMapper.selectBatchIds(treeIds);
            treeIdNameMap = equipInstructiontreePOS.stream().collect(Collectors.toMap(EquipInstructiontreePO::getId, EquipInstructiontreePO::getTreeName));
        }
        List<InstructionPageVO> res = new ArrayList<>(records.size());
        InstructionPageVO instructionPageVO;
        long i = 1;
        for (EquipInstructionValuePOWithBLOBs record : records) {
            instructionPageVO = new InstructionPageVO();
            instructionPageVO.setId(record.getId());
            instructionPageVO.setSerialNum(i);
            instructionPageVO.setArchivesAddress(record.getArchivesAddress());
            instructionPageVO.setDoCount(record.getDoCount() == null ? null : record.getDoCount().toString());
            instructionPageVO.setNbAddress(record.getNbAddress());
            instructionPageVO.setPnReceiveTime(record.getPnReceiveTime());
            instructionPageVO.setReceiveDesc(record.getReceiveDesc());
            instructionPageVO.setSendDesc(treeIdNameMap.get(record.getTreeId()));
            instructionPageVO.setSendDesc2(treeIdNameMap.get(record.getTreeId()));
            instructionPageVO.setPnSendTime(record.getPnSendTime());
            instructionPageVO.setSend("指令详情");
            instructionPageVO.setReceive(StrUtil.isBlank(record.getPnReceiveTime()) ? "未完成" : "完成");
            instructionPageVO.setUsername(record.getUsername());
            instructionPageVO.setState(SystemConsts.InstructionStateEnum.getValueNameByValue(record.getState()));
            res.add(instructionPageVO);
            i++;
        }
        return res;
    }
}
